﻿using Common.DataBase.Implement;
using Common.DataBase.Interface;
using Common.DataBase.Model;
using Common.ExtendMethod;
using Common.Utils;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.IO;
using System.Text;
using System.Windows.Forms;

namespace GenerateTool {
  public partial class FormMain : Form {

    private static Logger _logger = Logger.GetLogger(typeof(FormMain));
    private ISQLHelper _sqlHelper = null;
    private List<TableInfo> _tableInfoList = null;

    public FormMain() {
      InitializeComponent();
      _sqlHelper = new SQLiteHelper();
#if DEBUG
      this.txtProjectName.Text = "ScanFile";
#endif
    }


    /// <summary>
    /// 选择Modal存放路径
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void btnModal_Click(object sender, EventArgs e) {
      if(folderBrowserDialog.ShowDialog() == DialogResult.OK) {
        txtModel.Text = folderBrowserDialog.SelectedPath;
      }
    }

    private void button_Click(object sender, EventArgs e) {
      _tableInfoList = _sqlHelper.GetAllUserTables();
      generateModel();
      generateDal();
    }



    private void generateModel() {
      string modelPath = Path.Combine(this.txtOutput.Text, this.txtProjectName.Text, "Model");
      Directory.CreateDirectory(modelPath);
      foreach(TableInfo table in _tableInfoList) {
        string tableName = table.TableName.FirstUpper() ;
        string fileName = Path.Combine(modelPath, tableName + ".cs");
        using(FileStream fileStream = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.Read)) {
          using(StreamWriter streamWriter = new StreamWriter(fileStream, Encoding.UTF8)) {
            streamWriter.WriteLine("using System;");
            streamWriter.WriteLine("using System.Collections.Generic;");
            streamWriter.WriteLine();
            streamWriter.WriteLine(string.Format("namespace {0}.{1}{{", this.txtProjectName.Text, this.txtModel.Text.Trim('.')));
            streamWriter.WriteLine(string.Format("\tpublic class {0} {{", tableName));
            foreach(string columName in table.Columns.Keys) {
              ColumnInfo column = table.Columns[columName];
              if(string.IsNullOrWhiteSpace(column.DefaultValue)) {

              }
              streamWriter.WriteLine();
              streamWriter.WriteLine(string.Format("\t\tprivate {0} _{1};", _sqlHelper.DataTypeMap[column.Type], column.Name));
              streamWriter.WriteLine(string.Format("\t\tpublic {0} {1}{{", _sqlHelper.DataTypeMap[column.Type], column.Name.FirstUpper()));
              streamWriter.WriteLine(string.Format("\t\t\tget{{ return _{0}; }}", column.Name));
              streamWriter.WriteLine(string.Format("\t\t\tset{{ _{0} = value; }}", column.Name));
              streamWriter.WriteLine("\t\t}");
            }
            streamWriter.WriteLine("\t}");
            streamWriter.WriteLine("}");
          }
        }
      }
    }


    private void generateDal() {
      DbConnection connection = _sqlHelper.OpenConnection();
      string dbNameSpace = connection.GetType().Namespace;
      connection.Close();
      string modelPath = Path.Combine(this.txtOutput.Text, this.txtProjectName.Text, "Dal");
      Directory.CreateDirectory(modelPath);
      foreach(TableInfo table in _tableInfoList) {
        string tableName = table.TableName.FirstUpper();
        string fileName = Path.Combine(modelPath, tableName + ".cs");
        using(FileStream fileStream = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.Read)) {
          using(StreamWriter streamWriter = new StreamWriter(fileStream, Encoding.UTF8)) {
            streamWriter.WriteLine("using System;");
            streamWriter.WriteLine("using System.Data;");
            streamWriter.WriteLine("using System.Text;");
            streamWriter.WriteLine(string.Format("using {0};", dbNameSpace));
            streamWriter.WriteLine(string.Format("using {0};", typeof(ISQLHelper).Namespace));
            streamWriter.WriteLine(string.Format("using {0};", _sqlHelper.GetType().Namespace));
            streamWriter.WriteLine(string.Format("using {0};", typeof(Logger).Namespace));
            streamWriter.WriteLine("using System.Data.Common;");
            streamWriter.WriteLine("//using Maticsoft.DBUtility;//Please add references");

            streamWriter.WriteLine();
            streamWriter.WriteLine(string.Format("namespace {0}.{1}{{", this.txtProjectName.Text, this.txtDal.Text.Trim('.')));
            streamWriter.WriteLine();
            streamWriter.WriteLine(string.Format("\tpublic partial class {0}Dal {{", tableName));

            streamWriter.WriteLine();
            streamWriter.WriteLine("\t\t/// <summary>");
            streamWriter.WriteLine("\t\t///日志处理引用");
            streamWriter.WriteLine("\t\t/// </summary>");
            streamWriter.WriteLine(string.Format("\t\tprivate Logger _logger = Logger.GetLogger(typeof({0}Dal));", tableName));

            streamWriter.WriteLine();
            streamWriter.WriteLine("\t\t/// <summary>");
            streamWriter.WriteLine("\t\t/// 数据库操作引用");
            streamWriter.WriteLine("\t\t/// </summary>");
            streamWriter.WriteLine("\t\tprivate ISQLHelper _sqlHelper = null;");


            /// <summary>
            /// 构造函数
            /// </summary>
            streamWriter.WriteLine();
            streamWriter.WriteLine("\t\t/// <summary>");
            streamWriter.WriteLine("\t\t/// 构造函数");
            streamWriter.WriteLine("\t\t/// </summary>");
            streamWriter.WriteLine(string.Format("\t\tpublic {0}Dal(){{",tableName));
            streamWriter.WriteLine(string.Format("\t\t\t _sqlHelper = new {0}(); ", _sqlHelper.GetType().Name));
            streamWriter.WriteLine("\t\t}");
            streamWriter.WriteLine();





            string primaryKeyParameter = string.Empty;
            string primaryKeyWhere = string.Empty;
            string primaryKeyParameterArray = string.Empty;
            foreach(string columName in table.Columns.Keys) {
              ColumnInfo column = table.Columns[columName];
              if(column.IsPrimary == true) {
                if(string.IsNullOrWhiteSpace(primaryKeyParameter)) {
                  primaryKeyParameter = string.Format("{0} {1}", _sqlHelper.DataTypeMap[column.Type], column.Name);
                  primaryKeyWhere = string.Format(" {0} = @{0} ", column.Name);
                  primaryKeyParameterArray = string.Format("\t\t\t\tnew SQLiteParameter(\"@{0}\", {1})", column.Name, column.Name);
                } else {
                  primaryKeyParameter = string.Format("{0}, {1} {2}", primaryKeyParameter, _sqlHelper.DataTypeMap[column.Type], column.Name);
                  primaryKeyWhere = string.Format(" {0} = @{0} AND {1} ", column.Name, primaryKeyWhere);
                  primaryKeyParameterArray = string.Format("{2},\r\n\t\t\t\tnew SQLiteParameter(\"@{0}\", {1})", column.Name, column.Name, primaryKeyParameterArray);
                }
                
              }
            }

            if(!string.IsNullOrEmpty(primaryKeyParameter)) {
              //是否存在该记录的方法
              streamWriter.WriteLine(string.Format("\t\t/// <summary>"));
              streamWriter.WriteLine(string.Format("\t\t/// 是否存在该记录"));
              streamWriter.WriteLine(string.Format("\t\t/// </summary>"));
              streamWriter.WriteLine(string.Format("\t\tpublic bool Exists({0}) {{", primaryKeyParameter));


              streamWriter.WriteLine(string.Format("\t\t\tStringBuilder strSql = new StringBuilder();"));
              streamWriter.WriteLine(string.Format("\t\t\tstrSql.Append(\"SELECT COUNT(1) FROM {0}\");", tableName));
              streamWriter.WriteLine(string.Format("\t\t\tstrSql.Append(\" WHERE {0}\");", primaryKeyWhere));
              streamWriter.WriteLine(string.Format("\t\t\tDbParameter[] parameters = {{", tableName));
              streamWriter.WriteLine(primaryKeyParameterArray);
              streamWriter.WriteLine(string.Format("\t\t\t }};"));
              
              streamWriter.WriteLine(string.Format("\t\t\tint count = (int)_sqlHelper.ExecuteScalar(strSql.ToString(),parameters);", tableName));
              streamWriter.WriteLine("\t\t\treturn count > 0;");
              streamWriter.WriteLine("\t\t}");

            }

            //        /// <summary>
            //        /// 是否存在该记录
            //        /// </summary>
            //public bool Exists(int id) {
            //  StringBuilder strSql = new StringBuilder();
            //  strSql.Append("select count(1) from disks");
            //  strSql.Append(" where id=@id");
            //  SQLiteParameter[] parameters = {
            //      new SQLiteParameter("@id", DbType.Int32,4)
            //  };
            //  parameters[0].Value = id;

            //  return DbHelperSQLite.Exists(strSql.ToString(), parameters);
            //}










            foreach(string columName in table.Columns.Keys) {
              ColumnInfo column = table.Columns[columName];
              if(string.IsNullOrWhiteSpace(column.DefaultValue)) {

              }
              streamWriter.WriteLine();
              streamWriter.WriteLine(string.Format("\t\tprivate {0} _{1};", _sqlHelper.DataTypeMap[column.Type], column.Name));
              streamWriter.WriteLine(string.Format("\t\tpublic {0} {1}{{", _sqlHelper.DataTypeMap[column.Type], column.Name.FirstUpper()));
              streamWriter.WriteLine(string.Format("\t\t\tget{{ return _{0}; }}", column.Name));
              streamWriter.WriteLine(string.Format("\t\t\tset{{ _{0} = value; }}", column.Name));
              streamWriter.WriteLine("\t\t}");
            }
            streamWriter.WriteLine("\t}");
            streamWriter.WriteLine("}");
          }
        }
      }
    }

  }
}
